package com.zxq.ai.application.api.impl;

import com.zxq.common.middleware.DistributedID;
import com.zxq.common.utils.JsonUtil;
import com.zxq.ai.application.api.ICUserActivity;
import com.zxq.ai.application.exception.*;
import com.zxq.ai.application.helper.TransactionManagerProxy;
import com.zxq.ai.application.repository.CollectActivityParticipantRecordRepository;
import com.zxq.ai.application.repository.CollectCardActivityRepository;
import com.zxq.ai.application.repository.RewardRedeemTaskRepository;
import com.zxq.ai.domain.activity.Activity;
import com.zxq.ai.domain.activity.ActivityParticipantRecord;
import com.zxq.ai.domain.activity.CollectCardActivityParticipantRecord;
import com.zxq.ai.domain.activity.CollectCardActivity;
import com.zxq.ai.domain.enums.ActivityParticipantRecordStatus;
import com.zxq.ai.domain.enums.ActivityType;
import com.zxq.ai.domain.exception.*;
import com.zxq.ai.domain.reward.RewardRedeemTask;
import com.zxq.ai.domain.service.ActivityDomain;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.constructor.DuplicateKeyException;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 收集订单 兑换 优惠券 服务 【客户端】
 */
@Service
public class CUserCollectOrderActivity implements ICUserActivity {

    @Resource
    private TransactionManagerProxy transactionManagerProxy;
    @Resource
    private CollectCardActivityRepository collectCardActivityRepository;
    @Resource
    private CollectActivityParticipantRecordRepository collectActivityParticipantRecordRepository;
    @Resource
    private RewardRedeemTaskRepository rewardRedeemTaskRepository;
    @Resource
    private ActivityDomain activityDomain;
    @Resource
    private DistributedID distributedID;



    @Override
    public void redeemReward(Long activityId, Long userId) {
        CollectCardActivity activity = collectCardActivityRepository.queryByActivityId(activityId);
        // activity 有效性校验
        if (Objects.isNull(activity)) {
            throw new ActivityNotExistException(String.format("活动不存在：%s", activityId));
        }
        activity.validityChecking();

        // 1、查询参与记录
        List<CollectCardActivityParticipantRecord> recordList =
                collectActivityParticipantRecordRepository.queryByUserIdAndStatus(activityId, userId, ActivityParticipantRecordStatus.NOT_REDEEMED);
        if (CollectionUtils.isEmpty(recordList)) {
            throw new CollectCardNotExistException("没有可兑换的订单号");
        }

        // 2、兑换奖励：
        Pair<RewardRedeemTask, List<ActivityParticipantRecord>> pair = activityDomain.redeemReward(activity, recordList, userId);

        RewardRedeemTask redeemTask = pair.getLeft();
        List<ActivityParticipantRecord> redeemRecordList = pair.getRight();
        if (CollectionUtils.isEmpty(redeemRecordList)) {
            throw new NotMeetRewardCondition("没有可兑换的订单号");
        }

        transactionManagerProxy.execute(() -> {
            collectActivityParticipantRecordRepository.markRedeemed(redeemRecordList);
            rewardRedeemTaskRepository.batchInsert(redeemTask);
        });

    }


    /**
     * 收藏卡片
     * @param activityId
     * @param userId
     * @param orderId
     */
    public void add(Long activityId, Long userId, String orderId) {
        // 1、参数校验
        if (activityId == null || userId == null || StringUtils.isBlank(orderId)) {
            throw new IllegalArgumentException("活动参与参数缺失");
        }

        // 2、判断活动是否存在
        Activity activity = collectCardActivityRepository.queryByActivityId(activityId);
        if (activity == null) {
            throw new ActivityNotExistException(String.format("活动不存在：%s", activityId));
        }

        if (activity.getActivityType() != ActivityType.COLLECT_CARD) {
            throw new ActivityTypeInvalidException(String.format("活动类型不匹配：%s", activity.getActivityType()));
        }

        // 3、判断订单号是否有效


        // 4、添加参与记录
        try {
            collectActivityParticipantRecordRepository.add(activityId, userId, orderId);
        } catch (DuplicateKeyException e) {
            throw new CollectCardAddException("活动参与记录已存在");
        }

    }

    /**
     * 取消收藏
     * @param activityId
     * @param userId
     * @param orderIdList
     */
    public void remove(Long activityId, Long userId, List<String> orderIdList) {

        List<CollectCardActivityParticipantRecord> recordList = collectActivityParticipantRecordRepository.queryByOrderIds(activityId, orderIdList);
        if (CollectionUtils.isEmpty(recordList)) {
            throw new CollectCardRemoveException("活动参与记录不存在");
        }

        // 校验订单号是否都存在
        List<String> dbOrderIdList = recordList.stream()
                .filter(e -> Objects.equals(e.getUserId(), userId))
                .map(CollectCardActivityParticipantRecord::getCardId)
                .distinct()
                .collect(Collectors.toList());
        List<String> notFoundOrderIdList = ListUtils.subtract(orderIdList, dbOrderIdList);
        if (CollectionUtils.isNotEmpty(notFoundOrderIdList)) {
            throw new CollectCardRemoveException("部分活动参与记录不存在，请重试" + JsonUtil.toJson(notFoundOrderIdList));
        }

        // 删除参与记录
        List<Long> recordIdList = recordList.stream().map(CollectCardActivityParticipantRecord::id).distinct().toList();
        try {
            collectActivityParticipantRecordRepository.remove(recordIdList);
        } catch (Exception e) {
            throw new CollectCardRemoveException("活动参与记录不存在");
        }

    }

}
